﻿using DeviceDetectorNET;
using HCMS.CommonDtos;
using HCMS.Extensions;
using HCMS.IServices.Manage;
using HCMS.Web.Manage.Filter;
using Microsoft.AspNetCore.Mvc;
using System.Reflection;
using System.Xml.Linq;

namespace HCMS.Web.Manage.Controllers.Module.Logs
{
    /// <summary>
    /// 管理员 操作 日志
    /// </summary>
    public class AdminActionLogsController : ModuleController
    {
        private readonly IAdminActionLogsAppService adminActionLogsAppService;
        private readonly IAdminAppService adminAppService;

        public AdminActionLogsController(
            IAdminActionLogsAppService adminActionLogsAppService,
            IAdminAppService adminAppService)
        {
            this.adminActionLogsAppService = adminActionLogsAppService;
            this.adminAppService = adminAppService;
        }

        #region 列表
        /// <summary>
        /// 列表
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult List()
        {
            return View($"{BasePath}/Logs/AdminActionLogs/List.cshtml");
        }

        /// <summary>
        /// 列表 Ajax
        /// </summary>
        /// <returns></returns>
        [ActionName("List")]
        [HttpPost]
        public async Task<IActionResult> PostList()
        {
            var searchArgs = new SearchArgsDto()
            {
                SearchName = Request.Form["searchName"].ToString(""),
                SearchKey = Request.Form["searchKey"].ToString("")
            };

            var pager = new PagerArgsDto()
            {
                CurrentPageIndex = Request.Form["page"].ToInt(1),
                PageSize = Request.Form["limit"].ToInt(10)
            };

            // 获取包含 XML 注释的文档
            XDocument? xmlDocumentation = GetCurrentXMLDoc();

            #region 中文搜索 XML 文档描述的【控制器、方法名称】注释信息
            if (!string.IsNullOrWhiteSpace(searchArgs.SearchName) && !string.IsNullOrWhiteSpace(searchArgs.SearchKey) &&
                Array.IndexOf(["controllerName", "actionName"], searchArgs.SearchName) > -1 &&
                xmlDocumentation != null)
            {
                var summaryElement = xmlDocumentation.Descendants("member")
                         ?.Elements("summary")
                         ?.ToList();
                if (summaryElement != null && summaryElement.Any())
                {
                    var controllerNameList = new List<string>();
                    var actionNameList = new List<string>();

                    foreach (var item in summaryElement)
                    {
                        var summaryValue = item?.Value?.Trim();
                        summaryValue = summaryValue ?? "";

                        if (!summaryValue.Contains(searchArgs.SearchKey)) { continue; }

                        var parentMemberName = item?.Parent?.Attributes("name")?.FirstOrDefault()?.Value;

                        if (string.IsNullOrWhiteSpace(parentMemberName) || parentMemberName.IndexOf(".") == -1)
                        {
                            continue;
                        }

                        // 控制器名称 匹配
                        if (searchArgs.SearchName.IsSame("controllerName") && parentMemberName.EndsWith("Controller"))
                        {
                            var currentControllerName = parentMemberName.Substring(parentMemberName.LastIndexOf(".") + 1);
                            currentControllerName = currentControllerName.Replace("Controller", "");
                            controllerNameList.Add(currentControllerName);
                        }
                        // 方法名称 匹配
                        else if (searchArgs.SearchName.IsSame("actionName") && !parentMemberName.EndsWith("Controller") &&
                                 parentMemberName.IndexOf("Controller.") > -1)
                        {
                            var currentActionName = parentMemberName.Substring(parentMemberName.LastIndexOf("Controller.") + "Controller.".Length);
                            if (currentActionName.IndexOf("(") > -1) // 如果方法有参数，就去掉参数信息，只需要具体的方法名称
                            {
                                currentActionName = currentActionName.Substring(0, currentActionName.IndexOf("("));
                            }
                            actionNameList.Add(currentActionName);
                        }
                    }

                    if (controllerNameList.Any())
                    {
                        searchArgs.SearchName = "controllerNameList";
                        searchArgs.SearchKey = string.Join(",", controllerNameList);
                    }
                    else if (actionNameList.Any())
                    {
                        searchArgs.SearchName = "actionNameList";
                        searchArgs.SearchKey = string.Join(",", actionNameList);
                    }
                }
            }
            #endregion

            var result = await adminActionLogsAppService.ManageList(searchArgs, pager);

            if (result.Data != null && result.Data.Any())
            {
                foreach (var item in result.Data)
                {
                    #region 【控制器、方法名称】转为中文注释说明
                    if (!string.IsNullOrWhiteSpace(item.ControllerName))
                    {
                        if (!string.IsNullOrWhiteSpace(item.ActionName))
                        {
                            var actionSummary = GetMemberSummary(xmlDocumentation, string.Format("{0}Controller.{1}", item.ControllerName, item.ActionName));
                            if (!string.IsNullOrWhiteSpace(actionSummary))
                            {
                                item.ActionName = actionSummary;
                            }
                        }

                        var controllerSummary = GetMemberSummary(xmlDocumentation, item.ControllerName + "Controller");
                        if (!string.IsNullOrWhiteSpace(controllerSummary))
                        {
                            item.ControllerName = controllerSummary;
                        }
                    }
                    #endregion
                }
            }

            return Json(new { code = 0, data = result.Data, count = result.PagerInfo.RowCount, msg = "ok" });
        }
        #endregion

        #region 详情
        /// <summary>
        /// 详情
        /// </summary>
        /// <returns></returns>
        public async Task<IActionResult> Detail(int id)
        {
            var model = await adminActionLogsAppService.BaseFirstOrDefaultAsync(t => t.Id == id);
            if (model == null)
            {
                return Content("没找到操作日志详情");
            }

            // 获取包含 XML 注释的文档
            XDocument? xmlDocumentation = GetCurrentXMLDoc();

            var controllerSummary = GetMemberSummary(xmlDocumentation, model.ControllerName + "Controller");
            var actionSummary = GetMemberSummary(xmlDocumentation, string.Format("{0}Controller.{1}", model.ControllerName, model.ActionName));

            ViewData["controllerSummary"] = controllerSummary;
            ViewData["actionSummary"] = actionSummary;

            var admin = await adminAppService.BaseFirstOrDefaultAsync(t => t.Id == model.AdminId);
            var adminName = string.Empty;
            if (admin != null)
            {
                adminName = admin.AdminName;
            }
            ViewData["adminName"] = adminName;

            return View($"{BasePath}/Logs/AdminActionLogs/Detail.cshtml", model);
        }
        #endregion

        //----------------- 私有方法 -------------------

        #region 获取当前项目 XML 注释文档
        /// <summary>
        /// 获取当前项目 XML 注释文档
        /// </summary>
        /// <remarks>
        /// 为了使这段代码工作，需要确保在当前【Web.Manage】项目文件中启用了XML注释文档的生成，
        /// 并且在编译后，XML文件会生成在你的输出目录中。 
        /// </remarks>
        /// <returns></returns>
        [DefaultPermission]
        public XDocument? GetCurrentXMLDoc()
        {
            XDocument? xmlDocumentation = null;
            string xmlDocumentationPath = $"{Assembly.GetExecutingAssembly().Location}".Replace(".dll", ".xml");
            if (System.IO.File.Exists(xmlDocumentationPath))
            {
                xmlDocumentation = XDocument.Load(xmlDocumentationPath);
            }

            return xmlDocumentation;
        }
        #endregion

        #region 获取特定成员的 XML 注释说明
        /// <summary>
        /// 获取特定成员的 XML 注释说明
        /// </summary>
        /// <param name="xmlDocumentation">当前项目 XML 注释文档</param>
        /// <param name="memberName">成员名称</param>
        /// <returns></returns>
        [DefaultPermission]
        public string GetMemberSummary(XDocument? xmlDocumentation, string memberName)
        {
            if (xmlDocumentation == null || string.IsNullOrWhiteSpace(memberName)) { return ""; }

            var summaryElement = xmlDocumentation.Descendants("member")
                                 ?.Where(e => e.Attribute("name").Value.Contains(memberName))
                                 ?.Elements("summary")
                                 ?.FirstOrDefault();

            return summaryElement != null ? summaryElement.Value.Trim() : "";
        }
        #endregion

    }
}
